package org.tote.dao;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.tote.model.Audit;
import org.tote.model.AuditOperationType;


@Repository
public class AuditDaoImpl implements AuditDao {
	
	@Autowired
	private SessionFactory sessionFactory;

	@Override
	public void save(Audit audit) {
		sessionFactory.getCurrentSession().save(audit);
	}

	@Override
	public void update(Audit audit) {
		sessionFactory.getCurrentSession().update(audit);
	}

	@Override
	public void remove(Audit audit) {
		sessionFactory.getCurrentSession().delete(audit);
	}

	@Override
	public Audit getById(Long id) {
		return (Audit) sessionFactory.getCurrentSession().get(Audit.class, id);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Audit> getAuditRecords(AuditOperationType type, Date beginDate, Date endDate, String userName, int page, int limit) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Audit.class);
		if (type != null){
			criteria.add(Restrictions.eq("type", type));
		}
		if (beginDate != null){
			criteria.add(Restrictions.ge("dateCreated", beginDate));
		}
		if (endDate != null){
			criteria.add(Restrictions.le("dateCreated", endDate));
		}
		if (userName != null){
			criteria.createCriteria("user").add(Restrictions.like("name", userName+"%"));
		}
		criteria.addOrder(Order.desc("dateCreated")).setFirstResult(page * limit).setMaxResults(limit);
		return criteria.list();
	}

	@Override
	public long getAuditCount(AuditOperationType type, Date beginDate, Date endDate, String userName) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Audit.class);
		if (type != null){
			criteria.add(Restrictions.eq("type", type));
		}
		if (beginDate != null){
			criteria.add(Restrictions.ge("dateCreated", beginDate));
		}
		if (endDate != null){
			criteria.add(Restrictions.le("dateCreated", endDate));
		}
		if (userName != null){
			criteria.createCriteria("user").add(Restrictions.like("name", userName+"%"));
		}
		criteria.setProjection(Projections.count("id"));
		return (Long)criteria.uniqueResult();
	}
}
